﻿using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;

namespace BackUpAnyWhere
{
    // The FolderTreeView class inherent the original TreeView and use for adding 
    // four new events to the TreeView control

    public class FolderTreeView : TreeView
    {
        private TreeNode currentNode;

        public FolderTreeView() : base()
        {
            // List of events which will be added to the Control
            this.MouseEnter += new EventHandler(FolderTreeView_MouseEnter);
            this.AfterSelect += new TreeViewEventHandler(FolderTreeView_AfterSelect);
            this.AfterCollapse += new TreeViewEventHandler(FolderTreeView_AfterCollapse);
            this.AfterExpand += new TreeViewEventHandler(FolderTreeView_AfterExpand);
        }

        private void FolderTreeView_MouseEnter(object sender, EventArgs e){}

        private void FolderTreeView_AfterSelect(object sender, TreeViewEventArgs e){}

        private void FolderTreeView_AfterCollapse(object sender, TreeViewEventArgs e){}

        private void FolderTreeView_AfterExpand(object sender, TreeViewEventArgs e)
        {
            currentNode = e.Node;
            RemoveFirstChildNode(currentNode);
            PopulateTreeView(currentNode.FullPath, currentNode);
        }

        private static void PopulateTreeView(string directoryValue, TreeNode parentNode)
        {
            try
            {
                // Get the directory list
                DirectoryInfo dir = new DirectoryInfo(directoryValue);
                
                // Sort the directories by copying it to a List
                List<string> subDirList = new List<string>();
                foreach (DirectoryInfo subDir in dir.GetDirectories())
                {
                    subDirList.Add(subDir.Name);
                }
                
                subDirList.Sort();

                // Now for each dir in the list, check whether it has childes and if so
                // add an empty childNode underneath, so it will show the + sign 
                foreach (String DirName in subDirList)
                {
                    TreeNode childNode = new TreeNode();
                    childNode.Text = DirName;
                    try
                    {
                        if (HasSubFolders(parentNode.FullPath.ToString() + "\\" + DirName))
                        {
                            parentNode.Nodes.Add(childNode);
                            childNode.Nodes.Add("");
                        }
                        else
                            parentNode.Nodes.Add(childNode);
                    }
                    catch (UnauthorizedAccessException)
                    {
                        /*
                         * If the current childNode has no access,
                         * we don't want to display it so it wont 
                         * confuse the user
                         */
                    }
                }
            }
            catch (UnauthorizedAccessException)
            {
                parentNode.Nodes.Add("- Access denied -");
            }
        }

        public static bool HasSubFolders(string directoryValue)
        {
            // Check whether the requested directory has childes
            DirectoryInfo ChildDir = new DirectoryInfo(directoryValue);
            if (ChildDir.GetDirectories().Length > 0)
                return true;

            return false;
        }

        private void RemoveFirstChildNode(TreeNode parentNode)
        {
            parentNode.Nodes.Clear();
        }
    }
}

